using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public enum EBattleAction
{
	Nothing = 0,
	RageSkill = 1,
	SummonFriend = 2,
	Attack,
	SupportAtk,
	SupportDef,
	Skill,
	OverdriveAttack,
	Moving,
	Max,
}

public enum ESkillType
{
	Rage,
	Heal,
	Normal,
}

public class SkillInfo
{
	public float prob;
	public DSkills skill;
	public bool isRage;
	//public bool isFriendSkill;
	public int prior;
	public bool isHealType;

	public void Init(DSkills _skill, UnitStat stat)
	{
		skill = _skill;
		prob = BattleFormula.GetSkillChance(skill, stat.critical);
		prior = GameData.Inst.GetSkillPrior(_skill.traitID);
		//isHealType = (skill.skillType==2);
//		Debug.Log(skill.traitID+" skill rateType="+skill.rateType+"  prob="+prob+"  prior="+prior);

	}

	public bool IsHealType()
	{
		return isHealType;
	}
}

public class BattlePawn : MonoBehaviour {

	public PawnManifest pawnManifest;
	public List<SkillInfo> skillList = new List<SkillInfo>();
	SkillInfo chosenSkill;
	SkillInfo rageSkill;
	//SkillInfo friendSkill;
	public UnitStat stat;
	//public UnitStat friendStat;

	public bool isPlayer;
	public int pid; //고유 아이디 식별자//
	public int hp;
	public int maxHp;
	public bool isDead;
	public bool isGoingToDie;// 죽은 이후에 액션을 하지못하게 방지...빠른 턴 적용이후 발생//
	public int mNo;  // 캐릭터 넘버. 배치될때 위에서부터 1,2,3,4 //
	public ECharModel myModel;
	public string myModelStr;
	public string myModelName;
	public EBattleAction myAction;
	public bool isActionComplete;
	public bool isHealCasting;

	public float atkOrder;//우선권 계산결과//
	public bool isAttackSide;//공격측인가//
	public bool isAtkOrderDetermined;//우선권 결정되었나//
	public bool bReserveSupportAttack; //원호 공격 여부 임시저장//

	float sumTimeForIdle2;// idle02 플레이하기위한 시간계산용//
	float idle2CheckDelay;

	bool isTargeted;
	public bool isPvpEnemy;
	public float addDelayAfterTurn;
	public bool isBoss;
	public bool isFriend = false;				//	현재 캐릭터가 친구의 캐릭터인지 여부( 공격측만 소유 )
	static int supportAttackCount;
	public static int totalSupportAtkCount; // 총 원호공격 발생횟수  1: dual  2: triple  3: burst //
	public bool isSupportAtkHappen;//원호 공격이 발생했는지 여부..//
	public bool isSupportAtkComplete;// 원호 공격이 발생한 이후 원호 공격 모션들이 모두 끝났는가..//
	public bool isDamageDelayed;//공격 모션 다 끝난 후 타겟 데미지 처리할때..//
	public int [] itemModelID; // 장착한 아이템 모델아이디 [0]:오른손, [1]:왼손//
	public bool isUltimateReady; //필살기 시전 준비중인가..//
	public int totalDamageForBoss;
	//public bool isProjectileCasting;
	public bool bTurnEnd; //일반공격시 턴 종료 판별 시점. 마지막 히트시점 바로 이후.//
	public int memModelID;
	//public bool isUsedByPool;
	public GameObject pawnGo;
	static int nPlayerSpawned;
	static int nEnemySpawned;

	//5vs5 전투 관련//
	public float attackCoolTime;
	public float sumCoolTime;
	public BattlePawn mytarget;
	public bool isRepresent;//열 대표//
	public int attackRange;//0:앞라인만 1:중앙라인까지 2:모든라인가능//
	//

	private List<AnimateMaterialChange> effectHitMaterialList = new List<AnimateMaterialChange>();

	[HideInInspector]
	public bool bReserveUseForPool;

	public List<SkinnedMeshRenderer> smRenderers = new List<SkinnedMeshRenderer>();
	public Transform lightProbeAnchorForSkill;
	public int supportGuardCount;
	public bool isAttackedBySkill;
	public HpBar hpBar;
	public int myCurLine;
	public int myInitialLine;
	public int myRow;
	public Vector3 startPosition;
	public bool shouldMoveForward;
	int nMoveStepSize;//한번에 이동할 칸수//

	void Start()
	{ 
		SetIdle2CheckDelay();
	}

	public bool IsEnemyPVE
	{
		get {
			if(!isPlayer && !isPvpEnemy)
				return true;
			return false;
		}
	}

	public bool IsPvpPlayer()
	{
		return (isPlayer || isPvpEnemy);
	}

	public bool IsCurActionPawn()//현재 턴 진행중인 아이인지..//
	{
		return (this== BattleManager.Instance.curActionPawn);
	}

	public void InitCombat()
	{
		InitAtkOrder();

	}

	public void InitVars()
	{
		isDead=false;
		isGoingToDie=false;
		supportGuardCount=0;
		ResetAttackCoolTime();
		nMoveStepSize=0;
		shouldMoveForward=false;
		myAction= EBattleAction.Nothing;
	}

	public void ResetAttackCoolTime()
	{
		if(BattleManager.Instance.Is5vs5New) {
			sumCoolTime=0;
			if(isPlayer)
				attackCoolTime = UnityEngine.Random.Range(BattleManager.Instance.config.PlayerCoolTimeMin, BattleManager.Instance.config.PlayerCoolTimeMax);
			else
				attackCoolTime = UnityEngine.Random.Range(BattleManager.Instance.config.EnemyCoolTimeMin, BattleManager.Instance.config.EnemyCoolTimeMax);
		}
	}

	public static GameObject CreatePawnGo(int _nLine)
	{
		GameObject playerPrefab=null;
		if(_nLine==2 || _nLine==3) {
			int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_1.Length);
			playerPrefab = BattleManager.Instance.config.playerPrefab_1[nPrefabIndex];
		}
		else if(_nLine==1 || _nLine==4) {
			int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_2.Length);
			playerPrefab = BattleManager.Instance.config.playerPrefab_2[nPrefabIndex];
		}
		else if(_nLine==0 || _nLine==5) {
			int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_3.Length);
			playerPrefab = BattleManager.Instance.config.playerPrefab_3[nPrefabIndex];
		}
		
		return Instantiate(playerPrefab) as GameObject;
	}

	public int InitChar5vs5(int nIndex, MemberModel memModel, bool _isPvpEnemy, bool _isEnemy, int _nLine) 
	{
		skillList.Clear();
		InitVars();
		myInitialLine = _nLine;
		myCurLine = _nLine;
		pid = BattleManager.Instance.pawnId;
		isPlayer = true;
		isFriend = false;
		if(_isPvpEnemy) {
			isPlayer=false;
			isPvpEnemy = true;
		}
		if(_isEnemy )
			isPlayer=false;
		
		maxHp = InitStat(memModel);
		if(maxHp==0) {
			Debug.LogError("maxHP 0.. temporariry set 100");
			maxHp = 100;
		}
		hp = maxHp;
		
		memModelID=0;

		myModelName = pawnGo.name;
		myModel = BattleResManager.FindCharModel( myModelName );
		myModelStr = myModel.ToString();
		
		itemModelID = new int[2];
		itemModelID[0]=0;
		itemModelID[1]=0;
		if( memModel.rightItem !=null) {
			itemModelID[0] = memModel.rightItem.itemInfo.modelID;
			Debug.Log("right item model id = "+itemModelID[0]);
		}
		if( memModel.leftItem !=null) {
			itemModelID[1] = memModel.leftItem.itemInfo.modelID;
			Debug.Log("leftItem  model id = "+itemModelID[1]);
		}

		if(myInitialLine==2 || myInitialLine==3) {
			attackRange=0;
		}
		else if(myInitialLine==1 || myInitialLine==4) {
			attackRange=0;
		}
		else if(myInitialLine==0 || myInitialLine==5) {
			attackRange=1;
		}
		
		isAttackSide = true;//항상 플레이어가 공격측..//
		if(_isPvpEnemy || _isEnemy)
			isAttackSide = false;
		
		effectHitMaterialList.Clear();
		// 이펙트(피격) 초기화.
		smRenderers.Clear ();
		SkinnedMeshRenderer [] smRenderersArr = pawnGo.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach(SkinnedMeshRenderer mren in smRenderersArr) {
			string meshName = mren.sharedMesh.name.ToLower();
			if(!meshName.StartsWith("wing") )
				smRenderers.Add (mren);
		}
		if(smRenderers.Count>=2) {
			Debug.Log ("smRenderers count over 2");
		}
		
		foreach(SkinnedMeshRenderer skrenderer in smRenderers) {
			
			string meshName = skrenderer.sharedMesh.name.ToLower();
			//				Debug.LogError("	skrenderer.sharedMesh.name  ="+meshName);
			//if(meshName.StartsWith(myModel.ToString().ToLower()) ) {
			
			//Debug.Log("skrenderer.localBounds.size = "+skrenderer.localBounds.size);
			// 카메라 frus culling에 걸리지 않도록 넉넉하게 크게//
			Bounds b = new Bounds(skrenderer.localBounds.center, skrenderer.localBounds.size * 3);
			skrenderer.localBounds = b;
			//Debug.Log("new skrenderer.localBounds.size = "+skrenderer.localBounds.size);
			
			
			if(skrenderer.gameObject.activeSelf) {
				AnimateMaterialChange effect = skrenderer.gameObject.GetComponent<AnimateMaterialChange>();
				
				//if (effect == null)
				if(effect!=null)
					Destroy(effect);
				AnimateMaterialChange newEffect = skrenderer.gameObject.AddComponent<AnimateMaterialChange>();
				
				if (BattleManager.Instance.effectHitMaterial == null)
					BattleManager.Instance.effectHitMaterial = Resources.Load("Material/Cha_Hit_01", typeof(Material)) as Material;
				
				newEffect.Target = BattleManager.Instance.effectHitMaterial;
				newEffect.Time = BattleManager.Instance.effectHitTime;
				effectHitMaterialList.Add(newEffect);
			}
		}
		///

		BattleManager.Instance.pawnId++;
		if(_isPvpEnemy)
			pawnGo.name = string.Format("pawn_pvp_enemy_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );   
		else if(_isEnemy)
			pawnGo.name = string.Format("pawn_enemy_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );   
		else
			pawnGo.name = string.Format("pawn_player_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );                   
		mNo = nIndex+1;
		pawnManifest = pawnGo.AddComponent<PawnManifest>();

		SetInitialPosition();

		pawnGo.SetActive(false);
		pawnManifest.Init(this, nIndex, isPlayer);

		SetBackPosition();

		if(hpBar==null) {
			GameObject hpBarPrefab;
			if(isPlayer) {
				if(BattleManager.Instance.hpBarPrefab_player==null)
					BattleManager.Instance.hpBarPrefab_player = Resources.Load("Prefab/UI/HpbarPanel_player") as GameObject;
				hpBarPrefab = BattleManager.Instance.hpBarPrefab_player;
			}
			else {
				if(BattleManager.Instance.hpBarPrefab_enemy==null)
					BattleManager.Instance.hpBarPrefab_enemy = Resources.Load("Prefab/UI/HpbarPanel_enemy") as GameObject;
				hpBarPrefab = BattleManager.Instance.hpBarPrefab_enemy;
			}
			GameObject hpBarGo = NGUITools.AddChild(BattleManager.Instance.uiRootTrans.gameObject, hpBarPrefab);
			hpBar = hpBarGo.GetComponent<HpBar>();
		}
		hpBar.gameObject.SetActive(false);
		if(isPlayer && BattleSetting.Instance.showPlayerHpBar)
			hpBar.gameObject.SetActive(true);
		if(!isPlayer && BattleSetting.Instance.showEnemyHpBar)
			hpBar.gameObject.SetActive(true);
		hpBar.Init (pawnManifest, hp, isPlayer);
		InitSkill(memModel);
		return pid;
	}

	public int InitChar(int nIndex, MemberModel memModel, bool _isPvpEnemy, bool _isEnemy, int _nLine)
	{
		skillList.Clear();
		InitVars();
		myInitialLine = _nLine;
		myCurLine = _nLine;
		pid = BattleManager.Instance.pawnId;
		isPlayer = true;
		isFriend = false;
		if(_isPvpEnemy) {
			isPlayer=false;
			isPvpEnemy = true;
		}
		if(_isEnemy )
			isPlayer=false;

		maxHp = InitStat(memModel);
		if(maxHp==0) {
			Debug.LogError("maxHP 0.. temporariry set 100");
			maxHp = 100;
		}
		hp = maxHp;

		memModelID=0;
		if(BattleCheat.Instance.cheatModel) {
			memModelID = BattleCheat.Instance.playerModelId[nIndex];
			if(_isPvpEnemy || _isEnemy)
				memModelID = BattleCheat.Instance.enemyModelId[nIndex];
		}
		else 
			memModelID = memModel.model;

		GameObject playerPrefab=null;
		if(BattleManager.Instance.Is5vs5New) {
			if(myInitialLine==2 || myInitialLine==3) {
				attackRange=0;
				int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_1.Length);
				playerPrefab = BattleManager.Instance.config.playerPrefab_1[nPrefabIndex];
			}
			else if(myInitialLine==1 || myInitialLine==4) {
				attackRange=0;
				int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_2.Length);
				playerPrefab = BattleManager.Instance.config.playerPrefab_2[nPrefabIndex];
			}
			else if(myInitialLine==0 || myInitialLine==5) {
				attackRange=1;
				int nPrefabIndex = UnityEngine.Random.Range(0, BattleManager.Instance.config.playerPrefab_3.Length);
				playerPrefab = BattleManager.Instance.config.playerPrefab_3[nPrefabIndex];
			}
			myModelName = playerPrefab.name;
		}
		else
			myModelName = GameData.Inst.ModelDefineDic[memModelID];
		myModel = BattleResManager.FindCharModel( myModelName );
		myModelStr = myModel.ToString();

		itemModelID = new int[2];
		itemModelID[0]=0;
		itemModelID[1]=0;
		if( memModel.rightItem !=null) {
			itemModelID[0] = memModel.rightItem.itemInfo.modelID;
			Debug.Log("right item model id = "+itemModelID[0]);
		}
		if( memModel.leftItem !=null) {
			itemModelID[1] = memModel.leftItem.itemInfo.modelID;
			Debug.Log("leftItem  model id = "+itemModelID[1]);
		}

		isAttackSide = true;//항상 플레이어가 공격측..//
		if(_isPvpEnemy || _isEnemy)
			isAttackSide = false;

		InitAtkOrder();

		if(pawnGo == null) {

			if(BattleManager.Instance.Is5vs5New)
				pawnGo = Instantiate(playerPrefab) as GameObject;
			else
				pawnGo = BattleResManager.CreatePawn(memModel.no, memModelID, isPlayer);
			

			effectHitMaterialList.Clear();
			// 이펙트(피격) 초기화.
			smRenderers.Clear ();
			SkinnedMeshRenderer [] smRenderersArr = pawnGo.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach(SkinnedMeshRenderer mren in smRenderersArr) {
				string meshName = mren.sharedMesh.name.ToLower();
				if(!meshName.StartsWith("wing") )
					smRenderers.Add (mren);
			}
			if(smRenderers.Count>=2) {
				Debug.Log ("smRenderers count over 2");
			}

			foreach(SkinnedMeshRenderer skrenderer in smRenderers) {
				
				string meshName = skrenderer.sharedMesh.name.ToLower();
//				Debug.LogError("	skrenderer.sharedMesh.name  ="+meshName);
				//if(meshName.StartsWith(myModel.ToString().ToLower()) ) {
				
				//Debug.Log("skrenderer.localBounds.size = "+skrenderer.localBounds.size);
				// 카메라 frus culling에 걸리지 않도록 넉넉하게 크게//
				Bounds b = new Bounds(skrenderer.localBounds.center, skrenderer.localBounds.size * 3);
				skrenderer.localBounds = b;
				//Debug.Log("new skrenderer.localBounds.size = "+skrenderer.localBounds.size);
				
				
				if(skrenderer.gameObject.activeSelf) {
					AnimateMaterialChange effect = skrenderer.gameObject.GetComponent<AnimateMaterialChange>();
					
					//if (effect == null)
					if(effect!=null)
						Destroy(effect);
					AnimateMaterialChange newEffect = skrenderer.gameObject.AddComponent<AnimateMaterialChange>();
					
					if (BattleManager.Instance.effectHitMaterial == null)
						BattleManager.Instance.effectHitMaterial = Resources.Load("Material/Cha_Hit_01", typeof(Material)) as Material;
					
					newEffect.Target = BattleManager.Instance.effectHitMaterial;
					newEffect.Time = BattleManager.Instance.effectHitTime;
					effectHitMaterialList.Add(newEffect);
//					Debug.Log (meshName+"   effectHitMaterialList Added ");
				}
				//}
			}
//			Debug.Log(" smRenderers.Count ="+smRenderers.Count);
//			Debug.Log(" effectHitMaterialList.Count ="+effectHitMaterialList.Count);

		}

//		if(BattleManager.Instance.bMassBattle) {
//			myModel = BattleResManager.charModelMassTest;
//			char [] seperator = {'('};
//			string [] prefabNames = pawnGo.name.Split( seperator );
//			myPrefabName = prefabNames[0];
//		}
		BattleManager.Instance.pawnId++;
		if(_isPvpEnemy)
			pawnGo.name = string.Format("pawn_pvp_enemy_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );   
		else if(_isEnemy)
			pawnGo.name = string.Format("pawn_enemy_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );   
		else
			pawnGo.name = string.Format("pawn_player_{0}_{1}_{2}",pid, myModel.ToString(),(nIndex+1) );                   
		mNo = nIndex+1;
		pawnManifest = pawnGo.MakeComponent<PawnManifest>();

		if(BattleManager.Instance.Is5vs5New) {
			SetInitialPosition();

		}
		else {
			if(_isPvpEnemy || _isEnemy) {
				pawnManifest.transform.parent = BattleManager.Instance.enemyPosParent;

				pawnManifest.transform.localPosition = BattleManager.Instance.enemyPos[nIndex].localPosition;
				pawnManifest.transform.localRotation = BattleManager.Instance.enemyPos[nIndex].localRotation;

				nEnemySpawned++;
			}
			else {
				pawnManifest.transform.parent = BattleManager.Instance.playerPosParent;

				pawnManifest.transform.localPosition = BattleManager.Instance.playerPos[nIndex].localPosition;
				pawnManifest.transform.localRotation = BattleManager.Instance.playerPos[nIndex].localRotation;
			
				nPlayerSpawned++;
			}
			pawnManifest.transform.parent = null;
			pawnManifest.transform.localScale = Vector3.one;
			startPosition = pawnManifest.transform.position;
		}
		//Debug.Log ("InitChar  "+pawnGo.name);
		pawnGo.SetActive(false);
		pawnManifest.Init(this, nIndex, isPlayer);

		if(BattleManager.Instance.Is5vs5New) {
			SetBackPosition();

		}

		if(hpBar==null) {
			GameObject hpBarPrefab;
			if(isPlayer) {
				if(BattleManager.Instance.hpBarPrefab_player==null)
					BattleManager.Instance.hpBarPrefab_player = Resources.Load("Prefab/UI/HpbarPanel_player") as GameObject;
				hpBarPrefab = BattleManager.Instance.hpBarPrefab_player;
			}
			else {
				if(BattleManager.Instance.hpBarPrefab_enemy==null)
					BattleManager.Instance.hpBarPrefab_enemy = Resources.Load("Prefab/UI/HpbarPanel_enemy") as GameObject;
				hpBarPrefab = BattleManager.Instance.hpBarPrefab_enemy;
			}
			GameObject hpBarGo = NGUITools.AddChild(BattleManager.Instance.uiRootTrans.gameObject, hpBarPrefab);
			hpBar = hpBarGo.GetComponent<HpBar>();
		}
		hpBar.gameObject.SetActive(false);
		if(isPlayer && BattleSetting.Instance.showPlayerHpBar)
			hpBar.gameObject.SetActive(true);
		if(!isPlayer && BattleSetting.Instance.showEnemyHpBar)
			hpBar.gameObject.SetActive(true);
		hpBar.Init (pawnManifest, hp, isPlayer);
		InitSkill(memModel);
		return pid;
	}

	public void SetInitialPosition()
	{
		if(isPlayer) {
			nPlayerSpawned++;
			if(BattleManager.Instance.nPlayerFrontLine==1)
				myCurLine++;
			else if(BattleManager.Instance.nPlayerFrontLine==0)
				myCurLine+=2;
		}
		else { 
			nEnemySpawned++;
			if(BattleManager.Instance.nEnemyFrontLine==4)
				myCurLine--;
			else if(BattleManager.Instance.nEnemyFrontLine==5)
				myCurLine-=2;
		}
		myRow = Battle5vs5Center.Instance.SetPos(  this, pawnManifest.transform , isPlayer, myCurLine);
		startPosition = pawnManifest.transform.position;
	}

	public void SetBackPosition()
	{
		Vector3 newPos = startPosition;
		if(isPlayer)
			newPos.x += 10;
		else
			newPos.x -= 10;
		pawnManifest.transform.position = newPos;
	}
	
	int InitStat(MemberModel memModel)
	{
		if(IsEnemyPVE)
			stat = memModel.m_StatWithItem;
		else {
			stat = memModel.CalcUnitStat();
			//봉혼석//
			if(isPlayer && UserData.Instance.m_IsUseSoulStone) {
				Debug.Log("before SoulStone atk="+stat.atk+"  cri="+stat.critical);
				stat.atk = (int) (stat.atk * 1.1f);
				stat.critical = (int) (stat.critical * 1.1f);
				Debug.Log("SoulStone modified atk="+stat.atk+"  cri="+stat.critical);
			}
			//싱크로//
			//	친구 캐릭터가 아닐때( 추가 조건 )
			if( ( isPlayer == true ) && ( isFriend == false ) )
			{
				foreach( DPartySync pSync in UserData.Instance.userModel.m_PartySincSuccessList)
				{
//					Debug.Log("DPartySync  "+pSync.syncID);
					List<int> pSyncTraits = pSync.traits;
					bool bHasSyncTraits = false;
					foreach(int traitID in pSyncTraits) {
						if(memModel.HasTrait(traitID) ) {
							bHasSyncTraits=true;
							break;
						}
					}
					if(bHasSyncTraits) {
//						Debug.Log("HasSyncTraits  syncid="+pSync.syncID);
						stat.IncreaseStat( pSync.targetAttribute, pSync.mod);
					}
				}
			}

		}
		//friendStat = stat;
//		Debug.Log("maxHP="+stat.maxHp);
		return stat.maxHp;
	}
	
	public void InitAtkOrder()
	{
		atkOrder = (float)stat.prior;
		isAtkOrderDetermined=false;
	}
	
	public bool IsAtkOrderFirst(float compareAtkOrder)
	{
		if(atkOrder>compareAtkOrder)
			return true;
		if(atkOrder==compareAtkOrder)
			return isAttackSide;
		return false;
	}

	void InitSkill(MemberModel memberModel)
	{
		DSkills[] skills = memberModel.GetSkills();
		for(int i=0; i<skills.Length; i++)
		{
			if(skills[i].traitID >=1 && skills[i].traitID <=10 ) // 종족 스킬은 현재 이름 정보가 없어서 일단 스킵//
				continue;
//			Debug.Log("init add skill  traitID="+skills[i].traitID+"  myModel="+myModel.ToString() );
			SkillInfo skillInfo = new SkillInfo();
			skillInfo.Init(skills[i], stat);
			//임시로 cleric모델일때 heal 스킬 지정//
			if(myModel == ECharModel.Cleric || myModel == ECharModel.Chanter) {
				Debug.Log("heal skill");
				skillInfo.isHealType = true;
			}
			skillList.Add(skillInfo);
		}

		if(skillList.Count>=2)
		{
			// prior이 낮은것(우선순위 높음)부터 우선 정렬
			skillList.Sort(
				delegate(SkillInfo p1, SkillInfo p2)
			    {
			        return p1.prior.CompareTo(p2.prior);
			    }
			);
		}

//		foreach(SkillInfo sinfo in skillList)
//			Debug.Log("log skill traitID="+sinfo.skill.traitID);

		if(isPlayer) {
			rageSkill = new SkillInfo();
			rageSkill.isRage = true;
			rageSkill.skill = new DSkills();
			if(skillList.Count>0)//임시 적용. 분노 스킬이름을 현재 가진 스킬을 가지고 세팅.  TODO. //
				rageSkill.skill.traitID = skillList[0].skill.traitID;
			//friendSkill = new SkillInfo();
			//friendSkill.isFriendSkill = true;
		}
	}



	public void ClearHpBar()
	{
		hpBar.Clear();
		hpBar.gameObject.SetActive(false);
	}

	public void ClearMe()
	{
//		foreach(AnimateMaterialChange effect in effectHitMaterialList)
//			Destroy(effect);
//		effectHitMaterialList.Clear();
		if(BattleManager.Instance.Is5vs5New)
			BattleUI.Instance.ClearDamageHUDText(isPlayer, mNo);
		else
			BattleUIManager.Instance.ClearDamageHUDText(isPlayer, mNo);
		pawnManifest.StopCurTake();
		pawnManifest.StopEventLineTween();
		ClearHpBar();
	}

	public void DestroyMe()
	{
		Debug.Log(gameObject.name +" DestroyMe "+memModelID);
		StartCoroutine("CoDestroyMe");

	}

	IEnumerator CoDestroyMe()
	{
		yield return new WaitForSeconds(5.0f);
		Destroy(pawnGo);
		Destroy(gameObject);
	}

	public bool IsMaxHP()
	{
		if(hp==maxHp)
			return true;
		return false;
	}

	public bool IsActionComplete()
	{
		if(isActionComplete)
			return true;
		return false;
	}

	bool IsNeadHeal()
	{
		//일단 임시로 hp상관없이 항상 힐//
		return true;

		if(isPlayer)
		{
			foreach(BattlePawn pawn in BattleManager.Instance.targetablePlayerList)
			{
				if(!pawn.IsMaxHP() )
					return true;
			}
		}
		else
		{
			foreach(BattlePawn pawn in BattleManager.Instance.targetableEnemyList)
			{
				if(!pawn.IsMaxHP() ) 
					return true;
			}
		}
		return false;

	}

	EBattleAction SelectAction()
	{
		if(BattleManager.Instance.bOverdriveMode)
		{
			return EBattleAction.OverdriveAttack;
		}
		else if(isPlayer && BattleManager.Instance.isRageSkillPrepared)
		{
			BattleManager.Instance.isRageSkillPrepared=false;
			return EBattleAction.RageSkill;
		}
		else
		{
			if(skillList.Count==0 || BattleCheat.Instance.noSkill || BattleCheat.Instance.IsAlwaysSupportAtk() )
				return EBattleAction.Attack;
			chosenSkill = ChooseSkill();

			if(chosenSkill!=null) {
				Debug.Log("chosenSkill traitId="+chosenSkill.skill.traitID);
				return EBattleAction.Skill;
			}
			else
				return EBattleAction.Attack;
		}
	}

	public bool CanDoAction()
	{
		return (!isDead && !isGoingToDie);
	}

	public void DoAction()
	{
		//while( !pawnManifest.IsIdlePlaying() )//다른 모션이 진행중이면 idle이 될때까지 기다리자.//
		//	yield return null;
		
		ClearUltimateReady();
		
		//// 턴시작 초기화 //
		isActionComplete=false;
		BattleManager.Instance.nTurn++;
		supportAttackCount=0;
		totalSupportAtkCount=0;
		isSupportAtkHappen=false;
		isSupportAtkComplete=true;
		isDamageDelayed=false;
		isHealCasting=false;
		PawnManifest.curSupportAtkHit=0;
		pawnManifest.hitCount=0;
		pawnManifest.isSupportAtkMove=false;
		BattleManager.Instance.curActionPawn = this;
		//isProjectileCasting=false;
		bTurnEnd = false;
		
		myAction = SelectAction();
		//BattleManager.Instance.statusCheck.curActionPawn = this;
		//BattleManager.Instance.statusCheck.curAction = myAction;
		if(myAction== EBattleAction.Attack)//일반 공격//
			StartCoroutine("CoAttack");
		else if(myAction== EBattleAction.Skill)//스킬//
		{
			bool isHealType = chosenSkill.IsHealType(); 
			if( isHealType && !IsNeadHeal() )
				StartCoroutine("CoAttack");
			else
				StartCoroutine( CoSkill(chosenSkill) );
		}
		else if(myAction== EBattleAction.RageSkill) {//필살기//
			BattleManager.Instance.AddTurnSeq(1);
			StartCoroutine( CoSkill(rageSkill) );
		}
		//		else if(myAction== EBattleAction.SummonFriend) {
		//			BattleManager.Instance.AddTurnSeq(2);
		//			StartCoroutine( CoSkill(friendSkill) );
		//		}
		else if(myAction == EBattleAction.OverdriveAttack) {
			StartCoroutine("CoOverdriveAttack");
		}
	}

	static float fLeastMotionWaitTime = 1.0f;
	BattlePawn supportDefensePawn;
	IEnumerator CoAttack()
	{
		if(BattleManager.Instance.Is5vs5New) {
			if(!CanDoAction())
			{
				TurnEnd ();
				yield break;
			}
			BattlePawn target = BattleManager.Instance.GetTargetOne5vs5(this);
			if(target==null) {
				TurnEnd ();
				yield break;
			}

//			while( !target.pawnManifest.IsIdleOrDamagePlaying() ) {
//				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.AttackTargetReady, this, target);
//				yield return null;
//			}
//			BattleManager.Instance.statusCheck.ClearWaitStatus();

			int damage = 0;
			if(isPlayer)
				damage = UnityEngine.Random.Range( BattleManager.Instance.config.atkPowerPlayerMin, BattleManager.Instance.config.atkPowerPlayerMax);
			else
				damage = UnityEngine.Random.Range( BattleManager.Instance.config.atkPowerEnemyMin, BattleManager.Instance.config.atkPowerEnemyMax);
			bool isTargetWillDie = target.CheckDieByThisDamage(damage);
			target.isAttackedBySkill=false;

			pawnManifest.ActionAttack5vs5(target, damage, true);

			while(!bTurnEnd) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.AttackTurnEnd, this);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();
			TurnEnd();
		}
		else {

			BattlePawn target = BattleManager.Instance.GetTargetOneByTaunt(isPlayer);
			if(target==null) {
				TurnEnd ();
				yield break;
			}
			while( !target.pawnManifest.IsIdleOrDamagePlaying() ) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.AttackTargetReady, this, target);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();

			if( this.isFriend == false )
				BattleUIManager.Instance.ShowStatusBarTurnOnEffect(isPlayer, mNo);
			int damage = BattleFormula.CalcNormalDamage(stat, target);
			bool isTargetWillDie = target.CheckDieByThisDamage(damage);
			target.isAttackedBySkill=false;
			string attackLog = string.Format("BattlePawn({0})[hp={1}] damage {2} to BattlePawn({3})[hp={4}]",pid, hp, damage, target.pid, target.hp);
			Debug.Log(attackLog);

			float fAttackMotionLength = 0;
			float fMotionWaitTime = 0;

			///// 원호 공격 , 원호 방어 발생하는지 체크 //
			if( BattleCheat.Instance.alwaysSupportDefense)
				isSupportAtkHappen = false;
			else
				isSupportAtkHappen = IsSupportAttackHappen(this, target);

			//원호 공격 발생했으나 이번 공격으로 바로 타겟이 죽는경우 취소
			if(isSupportAtkHappen) {
				if( isTargetWillDie )
					isSupportAtkHappen = false;
			}

			if(isSupportAtkHappen)
				isSupportAtkComplete=false;
			supportDefensePawn = CheckSupportDefense(target);
			bool isSupportDefPossible = (!isSupportAtkHappen && supportDefensePawn!=null);
			if(BattleCheat.Instance.noSupportDef)
				isSupportDefPossible = false;
			if(isSupportDefPossible) {//원호 방어가 발동되는 경우//
				Debug.LogError(" support def happen ===================== ");
				supportDefensePawn.myAction = EBattleAction.SupportDef;
				damage = BattleFormula.GetSupportDefDamageModified(stat, supportDefensePawn);

				fAttackMotionLength = pawnManifest.ActionAttackToSupportDefPawn(target, supportDefensePawn, damage);
				fMotionWaitTime = fAttackMotionLength - BattleSetting.Instance.nextTurnAheadTime;
				Debug.Log("fAttackMotionLength="+fAttackMotionLength+"  fMotionWaitTime="+fMotionWaitTime);
				if(fMotionWaitTime<fLeastMotionWaitTime)
					fMotionWaitTime=fLeastMotionWaitTime;//최소한 이정도는 기다리자..//


			}
			else {
				fAttackMotionLength = pawnManifest.ActionAttack(target, damage, !isBoss);
				fMotionWaitTime = fAttackMotionLength - BattleSetting.Instance.nextTurnAheadTime;
				Debug.Log("fAttackMotionLength="+fAttackMotionLength+"  fMotionWaitTime="+fMotionWaitTime);
				if(fMotionWaitTime<fLeastMotionWaitTime)
					fMotionWaitTime=fLeastMotionWaitTime;//최소한 이정도는 기다리자..//

			}

			while(!bTurnEnd) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.AttackTurnEnd, this);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();

			if(isSupportDefPossible) {
				// 원호 방어 UI 떴다 사라지는 딜레이가 길어서 원호방어자 모션 끝날때까지 기다리자.//
				while(supportDefensePawn.pawnManifest.IsSupportDefPlaying() ) {
					BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.SupportDefEnd, this, supportDefensePawn);
					yield return null;
				}
				BattleManager.Instance.statusCheck.ClearWaitStatus();
			}

			if(!isSupportAtkHappen) {
				TurnEnd();
			}

			if(isSupportAtkHappen) {
				while(!isSupportAtkComplete)//원호 공격자들 모션이 끝나기를 기다린다//
				{
					BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.SupportAtkAllEnd, this);
					yield return null;
				}
				BattleManager.Instance.statusCheck.ClearWaitStatus();
				TurnEnd();
			}
		}
	}

	void EventEndAttack()
	{
		//pawnManifest.PlayIdle();
	}

	void EventEndAttackToSupportDefPawn()
	{
		//pawnManifest.PlayIdle();
		pawnManifest.isAttackToSupportDef=false;
		pawnManifest.supportDefManifest=null;
		if(supportDefensePawn!=null) {
			supportDefensePawn.pawnManifest.isSupportDefMove=false;
			supportDefensePawn.myAction = EBattleAction.Nothing;
		}

	}

	IEnumerator CoOverdriveAttack()
	{
		BattlePawn target = BattleManager.Instance.GetTargetRandom(isPlayer, false);
		if(target==null) {
			myAction = EBattleAction.Nothing;
			isActionComplete=true;
			BattleManager.Instance.EndOverdriveMode();
			yield break;
		}
		int damage = BattleFormula.CalcNormalDamage(stat, target);
		bool isTargetWillDie = target.CheckDieByThisDamage(damage);
		if(isTargetWillDie)
			BattleManager.Instance.RemoveFromTargetList(target, false);
		yield return new WaitForSeconds(pawnManifest.ActionSupportAttack(target, damage, 0));
		//while(isProjectileCasting)
		//	yield return null;
		//pawnManifest.PlayIdle();
		if(myAction== EBattleAction.OverdriveAttack) { //오버드라이브 끝나고 공격턴 시작 상태일수도 있으므로 체크//
			myAction = EBattleAction.Nothing;
			isActionComplete=true;
		}
	}

	void TurnEnd()
	{
		if(!isActionComplete) {
			//BattleManager.Instance.DetachCamera();
			if(!BattleManager.Instance.Is5vs5New) {
				if( this.isFriend == false )
					BattleUIManager.Instance.ShowStatusBarTurnOffEffect(isPlayer, mNo);
				if(isSupportAtkHappen)
					BattleUIManager.Instance.HideCoAttackText();
			}
			//yield return new WaitForSeconds(BattleSetting.Instance.delayAfterTurn + addDelayAfterTurn);
			addDelayAfterTurn=0;
			isActionComplete=true;
			myAction = EBattleAction.Nothing;
			EventEndAttackToSupportDefPawn();
		}
	} 

	public void ForcePlayRageSkill()
	{
		this.StartCoroutine( this.CoSkill( this.rageSkill ) );
	}

	IEnumerator CoSkill(SkillInfo skillInfo)
	{
		BattlePawn target1 = null;
		BattlePawn [] targetList = new BattlePawn[0];

		ESkillType curSkillType = ESkillType.Normal;

		if(skillInfo.isRage)
		{
			curSkillType = ESkillType.Rage;
			while( !BattleManager.Instance.IsAllPawnIdle() )// 모든 애들이 idle모션으로 갈때까지 기다림..//
			{
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.RageSkillAllPawnIdle, this);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();
		}
		else if(skillInfo.IsHealType() ) {
			curSkillType = ESkillType.Heal;
		}
		else
		{
			curSkillType = ESkillType.Normal;
			target1 = BattleManager.Instance.GetTargetOneByTaunt(isPlayer);
			if(target1==null) {
				TurnEnd();
				yield break;
			}
			while( !target1.pawnManifest.IsIdleOrDamagePlaying() ) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.SkillTargetReady, this, target1);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();
		}

				
		if( this.isFriend == false)
			BattleUIManager.Instance.ShowStatusBarTurnOnEffect(isPlayer, mNo);

//		string tmpSkillName = "";
//		if(skillInfo.isRage)
//			tmpSkillName = "Rage Skill";
//		else if(skillInfo.isFriendSkill)
//			tmpSkillName = "Friend Attack";
//		else
//			tmpSkillName = string.Format("skill_{0}_{1}",skillInfo.skill.traitID, skillInfo.skill.targetNumber);

		int damage = 0;
		BattleUIManager.Instance.ShowSkillNameText(skillInfo);

		if(isBoss)
			isDamageDelayed=true;

		float fAttackMotionLength = 0;

		if(curSkillType == ESkillType.Rage)//필살기//
		{
			//BattleUIManager.Instance.ShowSuperGageBrokenOutAnimation();
			isDamageDelayed = true;
			BattleManager.Instance.ChangeBackground( "Cutscene_Bg_01" );
			BattleManager.Instance.SetRageCamera(true);
			Vector3 originalPos = pawnManifest.transform.position;
			Quaternion originalRot = pawnManifest.transform.rotation;
			HideExceptMe(true);
			targetList = BattleManager.Instance.GetPawnAll(isPlayer,false);

			RuntimeMeshChanger mesh_changer = pawnManifest.GetRuntimeMeshChanger();
			if( mesh_changer != null )
				mesh_changer.ChangeToHigh();
			fAttackMotionLength = pawnManifest.ActionRageSkill(targetList);
			yield return new WaitForSeconds(fAttackMotionLength);

			pawnManifest.transform.position = originalPos;
			pawnManifest.transform.rotation = originalRot;
			HideExceptMe(false);
			BattleManager.Instance.SetRageCamera(false);						
			BattleManager.Instance.ChangeBackground( "DefaultBG" );
			if( mesh_changer != null )
				pawnManifest.GetRuntimeMeshChanger().ChangeToLow();

//			if( this.isFriend == true )
//			{
//				//yield return new WaitForSeconds( 1 );
//				foreach( BattlePawn target in targetList )
//				{
//					damage = BattleFormula.GetFriendDamageModified( friendStat, target, targetList.Length );
//				}
//			}
		}
//		else if(skillInfo.isFriendSkill)
//		{
//			/*
//			isDamageDelayed = true;
//			targetList = BattleManager.Instance.GetTargetAll(isPlayer,false);
//			yield return new WaitForSeconds(1);
//			foreach(BattlePawn target in targetList) {
//				damage = BattleFormula.GetFriendDamageModified(friendStat, target, targetList.Length);
//			}
//			 */
//		}
		else if(curSkillType == ESkillType.Heal)
		{
			SetLightProbeForSkill(true);
			BattleManager.Instance.SetSkillCamera(true);
			isHealCasting=true;
			targetList = BattleManager.Instance.GetHealTargetAll(isPlayer);
			fAttackMotionLength = pawnManifest.ActionSkillHeal(targetList, skillInfo.skill.skillMod );
			//yield return new WaitForSeconds(fAttackMotionLength);
			while(!pawnManifest.isSkillActionEnd) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.SkillPlayEnd, this);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();
			isHealCasting=false;
			SetLightProbeForSkill(false);
			//BattleManager.Instance.SetSkillCamera(false);
		}
		else// if(skillInfo.skill.targetNumber >= 1 )
		{
			//if(isBoss)
			SetLightProbeForSkill(true);
			BattleManager.Instance.SetSkillCamera(true);

			damage = BattleFormula.GetSkillDamage(stat, skillInfo.skill, target1);
			target1.isAttackedBySkill=true;
			fAttackMotionLength = pawnManifest.ActionSkillAttack(target1, damage, !isBoss);
			//yield return new WaitForSeconds(fAttackMotionLength);
			while(!pawnManifest.isSkillActionEnd) {
				BattleManager.Instance.statusCheck.SetWaitStatus(EBattleWaitStatus.SkillPlayEnd, this);
				yield return null;
			}
			BattleManager.Instance.statusCheck.ClearWaitStatus();
			SetLightProbeForSkill(false);
			//if(isBoss)
			//BattleManager.Instance.SetSkillCamera(false);
		}
//		else {
//			Debug.Log("skill category not found !");
//		}

		//if(isActionComplete)//필살기 등에 의해 TurnEnd가 이미 불린경우//
		//	yield break;

		//pawnManifest.PlayIdle();

		if(isDamageDelayed) {
			//yield return new WaitForSeconds(0.1f);
			targetList = BattleManager.Instance.GetTargetAll(isPlayer,false);
			float maxDamLength=0;
			foreach(BattlePawn target in targetList) {
				if(curSkillType == ESkillType.Rage)
					damage = BattleFormula.GetRageDamageModified(stat, target, targetList.Length);
				if( this.isFriend == true )
					damage = BattleFormula.GetFriendDamageModified( stat, target, targetList.Length );
				//if(skillInfo.isFriendSkill)
				//	damage = BattleFormula.GetFriendDamageModified(friendStat, target, targetList.Length);
				target.OnDamage(damage, 1, damage, false);
				if( target.pawnManifest.GetTakeLength_Damage01() > maxDamLength )
					maxDamLength = target.pawnManifest.GetTakeLength_Damage01();
				if(curSkillType == ESkillType.Rage)
					BattleResManager.Instance.ShowUltimateHit(myModel.ToString(), target.pawnManifest.damagePointTrans);//필살기전용 hit이펙트//
			}

			yield return new WaitForSeconds(maxDamLength);
		}

		yield return new WaitForSeconds(addDelayAfterTurn);

		TurnEnd();
	}

	void SetLightProbeForSkill(bool bSet)
	{
		foreach(SkinnedMeshRenderer smRenderer in smRenderers) {
			if(bSet)
				smRenderer.lightProbeAnchor = lightProbeAnchorForSkill;
			else
				smRenderer.lightProbeAnchor = null;
		}
	}

	//이번 공격에 의해 죽을지 미리 체크.( 다음턴에 액션을 취하지않도록 방지) //
	public bool CheckDieByThisDamage(int _damage)
	{
		if(hp-_damage<=0)
		{
			//Debug.Log(name+"   CheckDieByThisDamage   To die  "+_damage+"   hp="+hp);
			isGoingToDie=true;
			return true;
		}
		isGoingToDie=false;
		return false;
	}

	public void OnDamage(int damage, int hitCount, int totalDamage, bool bSkipDamageAction)
	{
		if(BattleManager.Instance.Is5vs5New) {
			OnDamage5vs5(damage);
			return;
		}
		//Debug.Log("OnDamage  "+damage+"   isDead="+isDead+"    effectHitMaterialList.count="+effectHitMaterialList.Count);
		if(isDead)
			return;
		int _oldHP = hp;
		//if(hp-damage<0)
		//	damage=hp;

		// 이펙트(피격시 재질 변경).
		foreach (AnimateMaterialChange effectHit in effectHitMaterialList)
			effectHit.Change();
		
		hp -= damage;
		if(hp<0)
			hp=0;
		int _afterHP = hp;
		if(!bSkipDamageAction)// 애니메이션을 스킵할지 체크  ex.)원호 방어자가 맞는경우 스킵한다//
		{
			if( pawnManifest.IsIdleOrDamagePlaying() ) //idle이나 damage중에만 맞는 액션을 허용하도록.  공격 시작한후 맞는경우 데미지 take를 플레이하면 공격턴이 끝나지않는다. 이런 상황에 대해 좀더 체크해보아야한다//
				pawnManifest.ActionDamaged(damage,hp);
			else
				Debug.Log("  IsIdleOrDamagePlaying   skil damage animation ");
				
			BattleUIManager.Instance.UpdateMemberHpBarEffect(!isPlayer, isBoss, mNo, damage, totalDamage, hp, maxHp, hitCount);
			BattleManager.Instance.UpdateTotalHP(isPlayer, mNo,_afterHP-_oldHP, false);
			BattleUIManager.Instance.ShowDamageHUDText(isPlayer, mNo, damage, isAttackedBySkill);
		}
		hpBar.UpdateHP(hp);
		if(hp==0)
		{
			Debug.Log("Died");
			isDead=true;
			BattleManager.Instance.RemoveFromTargetList(this, isPlayer);
		}
		if(isPlayer)
			BattleManager.Instance.IncreaseRage(damage, maxHp);
		if(isBoss)
			totalDamageForBoss += damage;
	}

	public void OnGuard(int _damage)
	{
		supportGuardCount++;
		Debug.Log(myModelName+"  GUARD "+supportGuardCount);
		BattleUIManager.Instance.ShowCoDefenseBarEffect(isPlayer, mNo);
		BattleUIManager.Instance.ShowGuardHUDImage(isPlayer, mNo);
		//BattleManager.Instance.UpdateTotalHP(isPlayer, mNo, -_damage, false);
		BattleUIManager.Instance.UpdateMemberHpBarNoEffect(!isPlayer, mNo, _damage, _damage, hp, maxHp);
		BattleUIManager.Instance.ShowCoDefenseText(myModel,myModelName,supportGuardCount);
	}

	public void OnHeal(float healPercent)
	{
		int _oldHP = hp;
		int heal = (int)(maxHp * healPercent);
		hp += heal;
		if(hp>maxHp)
			hp=maxHp;
		int _afterHP = hp;
		hpBar.UpdateHP(hp);
		BattleManager.Instance.UpdateTotalHP(isPlayer, mNo, _afterHP-_oldHP, true);
		BattleUIManager.Instance.UpdateMemberHpBarNoEffect(!isPlayer, mNo, heal, 0, hp, maxHp);
		BattleUIManager.Instance.ShowhealHUDText(isPlayer, mNo, heal);
	}

	bool IsSupportAttackHappen(BattlePawn curActionPawn , BattlePawn target)
	{
		bool bSupportAttack=false;
		if(IsPvpPlayer()) 
		{
			List<BattlePawn> pawnList = GetMyPawnList();

			int nSupportAtkCount=0;
			foreach(BattlePawn playerPawn in pawnList)
			{
				playerPawn.bReserveSupportAttack = false;
				if(playerPawn != curActionPawn && !playerPawn.isDead && playerPawn.myAction== EBattleAction.Nothing && !target.isDead && !target.isGoingToDie)
				{
					if( CanSupportAttack(playerPawn, nSupportAtkCount) )
					{
						nSupportAtkCount++;
						totalSupportAtkCount = nSupportAtkCount;
						playerPawn.bReserveSupportAttack = true;
						bSupportAttack=true;
					}
				}
			}
		}
		return bSupportAttack;
	}

	bool CanSupportAttack(BattlePawn playerPawn, int nSupportAtkCount)
	{
		float prob = BattleFormula.GetSupportAtkProb(playerPawn.stat.supportAtk);
		if(Well512.Instance.NextFloat()<=prob || BattleCheat.Instance.CanSupportAttack(nSupportAtkCount))
		{
			if(!BattleCheat.Instance.noSupportAttack)
				return true;
		}
		
		return false;
	}

	public List<BattlePawn> GetMyPawnList()
	{
		if(isPvpEnemy)
			return BattleManager.Instance.enemyList;
		else
			return BattleManager.Instance.playerList;
	}

	public List<BattlePawn> GetMyPawnList(BattlePawn checkPawn)
	{
		if(checkPawn.isPvpEnemy)
			return BattleManager.Instance.enemyList;
		else
			return BattleManager.Instance.playerList;
	}

	public void CancelSupportAttack()
	{
		isSupportAtkComplete=true;
	}

	public void CheckSupportAttack(BattlePawn target)
	{
		if(!IsPvpPlayer() || target.isDead || target.isGoingToDie) {
			isSupportAtkComplete=true;
			isSupportAtkHappen=false;
			return;
		}
		Debug.Log(pawnManifest.name+"  CheckSupportAttack");
		StartCoroutine(CoCheckSupportAttack(target) );
	}

	IEnumerator CoCheckSupportAttack(BattlePawn target)
	{
		List<BattlePawn> pawnList = GetMyPawnList();

		foreach(BattlePawn playerPawn in pawnList)
		{
			if(playerPawn.bReserveSupportAttack)
			{
				playerPawn.bReserveSupportAttack=false;
				playerPawn.SupportAttack(target);
				yield return new WaitForSeconds(BattleSetting.Instance.supportAtkDelay);
			}
		}

		while(true)
		{
			bool isDoingSupportAtk=false;
			foreach(BattlePawn playerPawn in pawnList)
			{
				if(playerPawn.myAction == EBattleAction.SupportAtk) {
					isDoingSupportAtk = true;
					break;
				}
			}

			if(!isDoingSupportAtk)
				break;
			yield return null;
		}

		isSupportAtkComplete=true;
	}

	public void SupportAttack(BattlePawn target)
	{
		myAction = EBattleAction.SupportAtk;
		StartCoroutine(CoSupportAttack(target));
	}

	IEnumerator CoSupportAttack(BattlePawn target)
	{
		supportAttackCount++;
		int damage = BattleFormula.GetSupportAtkDamageModified(supportAttackCount, stat, target);
		BattleUIManager.Instance.ShowCoAttackBarEffect(isPlayer, mNo, supportAttackCount);
		yield return new WaitForSeconds(pawnManifest.ActionSupportAttack(target, damage, supportAttackCount));

		//pawnManifest.PlayIdle();
		myAction = EBattleAction.Nothing;
	}

	public BattlePawn CheckSupportDefense(BattlePawn target)
	{
		if(isBoss)
			return null;

		if(target.IsPvpPlayer())
		{
			List<BattlePawn> pawnList = GetMyPawnList(target);
			int maxDef = 0;
			BattlePawn maxDefPawn = null;

			//원호 방어할 폰을 찾는다//
			foreach(BattlePawn playerPawn in pawnList)
			{
				if(playerPawn != target && playerPawn.myAction== EBattleAction.Nothing && !playerPawn.isDead)
				{
					int def = playerPawn.stat.def;
					if(!BattleFormula.IsMeleeAttack(stat.atkType))
						def = playerPawn.stat.resist;
					if( playerPawn.stat.maxHp * def > maxDef) {
						maxDef = playerPawn.stat.maxHp * def;
						maxDefPawn = playerPawn;
					}
					if(BattleCheat.Instance.IsFixedSupportDefenser(playerPawn) ) {
						maxDefPawn = playerPawn;
						break;
					}
				}
			}

			if(maxDefPawn!=null) {
				float prob = BattleFormula.GetSupportDefProb(maxDefPawn.stat.supportDef);
				if(Well512.Instance.NextFloat()<=prob || BattleCheat.Instance.alwaysSupportDefense)
					return maxDefPawn;
			}

		}
		return null;
	}

	SkillInfo ChooseSkill()
	{
		bool isNeedHeal = IsNeadHeal();
		foreach(SkillInfo skillInfo in skillList) {
			if( skillInfo.IsHealType() && !isNeedHeal)
				continue;
			float prob = Well512.Instance.NextFloat();
			Debug.Log(skillInfo.skill.traitID+ "  ChooseSkill skillProb="+skillInfo.prob+"  prob="+prob);
			if(prob <= skillInfo.prob || BattleCheat.Instance.alwaysSkill)
				return skillInfo;
		}
		return null;
	}
	
	public void CheckPlayIdle2()
	{
		if(!isDead && pawnManifest.HasIdle2() && !pawnManifest.isPlayingIdle2  && pawnManifest.IsIdle01Playing()) {
			sumTimeForIdle2 += Time.deltaTime;
			if(!isTargeted && myAction == EBattleAction.Nothing ) {
				if( sumTimeForIdle2 > idle2CheckDelay) {
					int prob = Random.Range(0,100);
					if( prob < BattleSetting.Instance.idle2Prob)
						pawnManifest.PlayIdle2();
					sumTimeForIdle2 = 0;
					SetIdle2CheckDelay();
				}
			}
		}
	}

	void SetIdle2CheckDelay()
	{
		idle2CheckDelay = Random.Range(BattleSetting.Instance.idle2CheckDelayMin, BattleSetting.Instance.idle2CheckDelayMax);
		//Debug.Log(mNo+"  idle2CheckDelay="+idle2CheckDelay);
	}

	public void HideExceptMe(bool bHide)
	{
		foreach(BattlePawn pawn in BattleManager.Instance.playerList)
		{
			if(pawn!=this) {
//				pawn.pawnManifest.gameObject.SetActive(!bHide);
//				if(bHide)
//					pawn.pawnManifest.StopCurTake();
//				else
//					pawn.pawnManifest.PlayIdle();
				if(bHide)
					pawn.pawnManifest.transform.position = pawn.pawnManifest.transform.position + new Vector3(100,100,0);// SetActive로 처리하면 문제가 있어서 안보이는곳으로 이동//
				else
					pawn.pawnManifest.transform.position = pawn.pawnManifest.transform.position + new Vector3(-100,-100,0);
			}
		}
	} 

	public void Revive()
	{
		if(isDead && IsPvpPlayer()) {
			BattleManager.Instance.AddToTargetList(this, isPlayer);
			isDead=false;
			isGoingToDie=false;
			hp = maxHp;
			pawnManifest.PlayStandUp();
		}
	}

	public void SetUltimateReady()
	{
		isUltimateReady = true;
		BattleResManager.Instance.ShowUltimateReady(pawnManifest.transform);
	}

	public void ClearUltimateReady()
	{
		if(isUltimateReady) {
			BattleResManager.Instance.ClearUltimateReady();
			isUltimateReady=false;
		}
	}

	// 마지막 hit 이벤트시 발생//

	public void EventLastHit()
	{
		StartCoroutine("CoEventLastHit");
	}

	IEnumerator CoEventLastHit()
	{
		yield return new WaitForSeconds( BattleSetting.Instance.nextTurnAheadTime );
		bTurnEnd = true;
	}

//	public void SetAction(EBattleAction _action)
//	{
//		myAction = _action;
//	}

	void OnDamage5vs5(int damage)
	{
		if(isDead)
			return;
		int _oldHP = hp;

		// 이펙트(피격시 재질 변경).
		foreach (AnimateMaterialChange effectHit in effectHitMaterialList)
			effectHit.Change();
		
		hp -= damage;
		if(hp<0)
			hp=0;
		int _afterHP = hp;
		
		BattleUI.Instance.ShowDamageHUDText(isPlayer, mNo, damage, isAttackedBySkill);
	
		hpBar.UpdateHP(hp);

//		if(hp==0) {//for test
//			hp=1;
//			isGoingToDie=false;
//		}

		if(hp==0)
		{
			pawnManifest.ActionDie();
			isDead=true;
			BattleManager.Instance.RemoveFromTargetList5vs5(this, isPlayer);
		}
		if(isPlayer)
			BattleManager.Instance.IncreaseRage(damage, maxHp);

	}

	public void ForwardMove()
	{
		if(myAction== EBattleAction.Moving)
			return;

		myAction= EBattleAction.Moving;
		Battle5vs5Center.Instance.SetOccupied(this, false);

		int nFrontLineToMove = myCurLine;
		if(isPlayer) {
			nFrontLineToMove+=nMoveStepSize;
		}
		else {
			nFrontLineToMove-=nMoveStepSize;
		}

		pawnManifest.ActionMoveFoward(myRow, nMoveStepSize);

		myCurLine = nFrontLineToMove;
		Battle5vs5Center.Instance.SetOccupied(this, true);
	}

	public void ShouldMoveForward(int nStepSize)
	{
		shouldMoveForward=true;
		nMoveStepSize+=nStepSize;
	}

	public int WillBeLine
	{
		get {
			if(isPlayer)
				return myCurLine+nMoveStepSize;
			else
				return myCurLine-nMoveStepSize;
		}
	}

	public void MoveForNextEnemy()
	{
		pawnManifest.bEnterStageComplete=false;
		pawnManifest.MoveForNextEnemy();
	}

	public bool UpdateAction()
	{
		if(pawnManifest!=null && pawnManifest.bEnterStageComplete && CanDoAction() && myAction== EBattleAction.Nothing && pawnManifest.IsIdlePlaying()) {

			if(isPlayer && BattleManager.Instance.targetableEnemyList.Count==0)
				return true;
			if(shouldMoveForward) {
				shouldMoveForward=false;
				ForwardMove();
				nMoveStepSize=0;
			}
			else {
				sumCoolTime += Time.deltaTime;
				if(sumCoolTime>=attackCoolTime) {
					ResetAttackCoolTime();
					DoAction();
				}
			}
		}
		if(isDead)
			return true;
		return false;
	}
}
